﻿using System;
using System.ComponentModel;
using BrawlLib.SSBBTypes;
using BrawlLib.Wii.Models;
using System.Collections.Generic;

namespace BrawlLib.SSBB.ResourceNodes
{
    public unsafe class MDL0NormalNode : MDL0EntryNode
    {
        internal MDL0NormalData* Header { get { return (MDL0NormalData*)WorkingUncompressed.Address; } }
        //protected override int DataLength { get { return Header->_dataLen; } }

        internal List<MDL0PolygonNode> _polygons = new List<MDL0PolygonNode>();

        [Category("Normal Data")]
        public int TotalLen { get { return Header->_dataLen; } }
        [Category("Normal Data")]
        public int MDL0Offset { get { return Header->_mdl0Offset; } }
        [Category("Normal Data")]
        public int DataOffset { get { return Header->_dataOffset; } }
        [Category("Normal Data")]
        public int StringOffset { get { return Header->_stringOffset; } }
        [Category("Normal Data")]
        public int ID { get { return Header->_index; } }
        [Category("Normal Data")]
        public bool IsNBT { get { return Header->_isNBT != 0; } }
        [Category("Normal Data")]
        public int Format { get { return Header->_type; } }
        [Category("Normal Data")]
        public int Divisor { get { return Header->_divisor; } }
        [Category("Normal Data")]
        public int EntryStride { get { return Header->_entryStride; } }
        [Category("Normal Data")]
        public int NumEntries { get { return Header->_numVertices; } }

        //private Vector3[] _normals;
        //public Vector3[] Normals
        //{
        //    get { return _normals == null ? _normals = VertexCodec.Decode(Header) : _normals; }
        //    set { _normals = value; SignalPropertyChange(); }
        //}

        protected override bool OnInitialize()
        {
            //base.OnInitialize();

            if ((_name == null) && (Header->_stringOffset != 0))
                _name = Header->ResourceString;

            return false;
        }

        private VertexCodec _enc;
        protected override int OnCalculateSize(bool force)
        {
            _enc = VertexCodec.Evaluate(Normals, false);
            return _enc._dataLen.Align(0x20) + 0x20;
        }

        protected internal override void OnRebuild(VoidPtr address, int length, bool force)
        {
            MDL0NormalData* header = (MDL0NormalData*)address;

            header->_dataLen = length;
            header->_dataOffset = 0x20;
            header->_index = _entryIndex;
            header->_isNBT = 0;
            header->_type = (int)_enc._type;
            header->_divisor = (byte)_enc._scale;
            header->_entryStride = (byte)_enc._dstStride;
            header->_numVertices = (ushort)_enc._srcCount;

            _enc.Write(Normals, (byte*)header + 0x20);
            _enc.Dispose();
            _enc = null;
        }

        protected internal override void PostProcess(VoidPtr mdlAddress, VoidPtr dataAddress, StringTable stringTable)
        {
            MDL0NormalData* header = (MDL0NormalData*)dataAddress;
            header->_mdl0Offset = (int)mdlAddress - (int)dataAddress;
            header->_stringOffset = (int)stringTable[Name] + 4 - (int)dataAddress;
        }
    }
}
